/**
 * This file handles map initialization and events.
 * 
 * @author	Tobin Bradley
 * @license 	MIT
 */


/**
 * Globals specifically for OpenLayers Use
 */
var marker = null;


/**
 * Map Initialization
 * Note most of the varible items - map config, layers, initial extent, etc.,
 * are in config.js
 */
function initializeMap() {
	
	map = new L.Map('map', {attributionControl: false, minZoom: mapMinZoom, maxZoom: mapMaxZoom});
	
	/**
	* If localstorage values present, set zoom accordingly
	*/
	if (window.localStorage) {
		if (localStorage.getItem('gp_lastSelected_longitude') && localStorage.getItem('gp_lastSelected_latitude') && !(getUrlVars()["matid"] && getUrlVars()["category"])) {
			defaultMapCenter = [localStorage.getItem('gp_lastSelected_latitude'), localStorage.getItem('gp_lastSelected_longitude')];
			defaultMapZoom = 16;
			locationFinder("Address", 'master_address_table', 'objectid', localStorage.getItem('gp_lastSelected'));
		}
	}
	
	map.setView(new L.LatLng(parseFloat(defaultMapCenter[0]), parseFloat(defaultMapCenter[1])), defaultMapZoom);
		
	
	/*  Map toolbar  */
	// remove measure 
	$("label[for='measure']").remove();
	$("#measure").remove();
	// create buttons
	$("#mapcontrols").buttonset();
	$("#mapcontrols input:radio").click( function() { toolbar($(this)) });
	$("#toolbar").fadeIn("slow");
	
	
	/*  Coordinate display  */
     map.on('mousemove', function(event) {
          $("#toolbar-coords").text(event.latlng.lng.toFixed(3) + " " + event.latlng.lat.toFixed(3));
     });
	
	
	/* Layer Control */
	$("#layerswitcher").append("<ul></ul>");
     $.each(mapLayers, function(index, value) {
          value.isVisible ? checked = 'checked' : checked = '';
		if (value.isBaseLayer) {
				$("#layerswitcher ul").append('<li><input type="radio" name="baseLayers" id="' + index + '" class="layer" ' + checked + ' /><label for="' + index + '" title="' + value.alt + ' ' + value.attribution +'" >' + value.name + '</label></li>');
		}
		else {
			$("#layerswitcher ul").append('<li><input type="checkbox" id="' + index + '" class="layer" ' + checked + '/><label for="' + index + '" title="' + value.alt + ' ' + value.attribution +'" >' + value.name + '</label></li>');
			$('#opacitydll').append('<option value="' + index + '">' + value.name + '</option>');
          }
     });
     $('.layer').change(function(){
          // Drop all non-base layers
		$.each(map._layers, function(index, value) {
			if (value.options.id) map.removeLayer(value);
		});
		
		// process layer control
		$(".layer").each(function() {
			if ($(this).is(':checked') && !$(this).is(':disabled')) {
				value = mapLayers[this.id];
				if (value.wmsurl.indexOf("{x}") != -1) {  // Tiles
					map.addLayer(
						new L.TileLayer(
							value.wmsurl.replace(/\$/g,""),
							{
								id: value.id,
								isBaseLayer: value.isBaseLayer,
								attribution: value.attribution,
								minZoom: value.minZoom,
								maxZoom: value.maxZoom
							}
						)
					);
				}
				else {  // WMS
					map.addLayer(
						new L.TileLayer.WMS(
							value.wmsurl,
							{
								id: value.id,
								isBaseLayer: value.isBaseLayer,
								layers: value.layers,
								format: value.format,
								attribution: value.attribution,
								transparent: value.transparent,
								minZoom: value.minZoom,
								opacity: value.opacity,
								maxZoom: value.maxZoom
							}
						)
					);
				}
			}
		});
		
     });
	layerSwitcherZoomCheck();
	map.on("zoomend", function(event){ layerSwitcherZoomCheck(); });
	
	
	/*  Opacity Slider  */
     $("#layerOpacity").html("Layer Opacity: " + parseInt(mapLayers[$('#opacitydll').val()].opacity * 100 ) + "%");
     $('#opacitySlider').slider({range: "min", min: .1, max: 1, step: .05, value: mapLayers[$('#opacitydll').val()].opacity, slide: function(event, ui) {
          opacityDLLValue = $('#opacitydll').val();       
          mapLayers[opacityDLLValue].opacity = ui.value;          
          if ( $("#" + opacityDLLValue).is(":checked") ) {
			$(".layer").trigger("change");
          }  
          $("#layerOpacity").html("Layer Opacity: " + parseInt(ui.value * 100 ) + "%");
	 }});
     $('#opacitydll').change(function() {
          $("#opacitySlider").slider( "option", "value", mapLayers[$('#opacitydll').val()].opacity );
          $("#layerOpacity").html("Layer Opacity: " + parseInt(mapLayers[$('#opacitydll').val()].opacity * 100 ) + "%");
     });
	
}


/*  Check to see if layers in the layer control should be enabled/disabled based on zoom level  */
function layerSwitcherZoomCheck() {
	$(".layer").each(function() {
		id = this.id;
		value = mapLayers[id];
		if (parseInt(map.getZoom()) > value.maxZoom || parseInt(map.getZoom()) < value.minZoom) {
			$("#" + id).attr("disabled", true).next().css("color", "#D1D0CC");
		}
		else {
			$("#" + id).removeAttr("disabled").next().css("color", "inherit");
		}
	});
	$(".layer").trigger("change");
}


/**
 * Add layers to the map
 */
function addMapLayers() {
	$.each(mapLayers, function(index, value) { 
		if (value.isVisible) {
			if (value.wmsurl.indexOf("{x}") != -1) {
				map.addLayer(
					new L.TileLayer(
						value.wmsurl.replace(/\$/g,""),
						{
							id: value.id,
							isBaseLayer: value.isBaseLayer,
							attribution: value.attribution,
							minZoom: value.minZoom,
							maxZoom: value.maxZoom
						}
					)
				);
			}
			else {
				map.addLayer(
					new L.TileLayer.WMS(
						value.wmsurl,
						{
							id: value.id,
							isBaseLayer: value.isBaseLayer,
							layers: value.layers,
							format: value.format,
							attribution: value.attribution,
							transparent: value.transparent,
							minZoom: value.minZoom,
							maxZoom: value.maxZoom
						}
					)
				);
			}
		}
	});
}



/**
 * Perform identify based on map click. Note minimum zoom level of 16
 * @param {event} object
 */
function identify(event) {
	if (map.getZoom() >= 16) {
		url = pointOverlay(event.latlng.lng, event.latlng.lat, 4326, 'tax_parcels', 'pid', "", 'json', '?');
		$.getJSON(url, function(data){
			if (data.total_rows > 0 ) { 
				$.each(data.rows, function(i, item){
					url = wsbase + "v1/ws_mat_pidgeocode.php?format=json&callback=?";
					args = "&pid=" + urlencode(item.row.pid);
					url = url + args;
					$.getJSON(url, function(data) {
						if (data.total_rows > 0 ) {
							if (i == 0) locationFinder("Address", 'master_address_table', 'objectid', data.rows[0].row.objectid);
						}
					});
				}); 
			}
		});
	}
}


/*  Handle toolbar events  */
function toolbar(tool) {
     if (tool.attr("id") == "identify") {
          map.on('click', identify);
     }
	else map.off('click', identify);     
}


/**
 * Zoom to a latlong at a particular zoom level. 
 * @param {float} long
 * @param {float} lat
 * @param {integer} zoom
 */
function zoomToLonLat (lon, lat, zoom) {
	map.setView(new L.LatLng(parseFloat(lat), parseFloat(lon)), zoom);
}


/**
 * Add markers (vector) to the map.
 * Also removes popups and selects added feature.
 * @param {float} long
 * @param {float} lat
 * @param {featuretype} the type of feature/marker (0=address,1=facility,2=identify)
 * @param {label} the content to put in the popup
 */
function addMarker(lon, lat, featuretype, label) {
	zoomToLonLat(lon, lat, 16);
	
	if (null != marker) map.removeLayer(marker);
	marker = new L.Marker(new L.LatLng(parseFloat(lat), parseFloat(lon)));
	map.addLayer(marker);
	
	marker.bindPopup(label).openPopup();
	
	
	
}